{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 卷积的特性描述"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1. 局部相关性：因为卷积运算是对$n×n$范围内的数据进行计算，所以保持了数据的的局部相关性。另外每经过一层卷积得到的新的映射点对应原图的感受野就更大了。又由于卷积是对一定范围内的数据进行计算，所以有少量数据被遮挡对结果的影响也有限，即有一定程度的遮挡不变性\n",
    "2. 参数共享：对于一个卷积层，只是用同一卷积核在图像上滑动，而不是每个连接有一个不同的参数，这样又减少了很多参数。\n",
    "3. 平移宽容：就是无论特征在图像（或其他数据）什么位置都可以被卷积核处理到\n",
    "4. 缩放宽容：通长$25\\%$内缩放对识别结果影响不大\n",
    "5. 少许降维：比如valid方式就可以一定程度的降维。\n",
    "6. 对输入尺寸不做任何要求：卷积层的卷积核大小是固定（设计是多大就是多大），不受输入图像尺寸的影响，对比全连接神经网络权重W尺寸受输入影响有很大优势"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 为什么卷积的效果要比全连接网络好，给出至少2点理由，每点10分。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1. 利用卷积和池话多有局部相关性的数据（比如图像）进行预处理，可以有效地提取特征，减少网络训练受到的噪声影响。而且可以降维，减少神经元和隐层数量便于训练，同时系统的鲁棒性好。\n",
    "2. 不考虑数据量大的情况，图像使用全连接神经网络想要取得好的效果，需要有很多隐层。大数量级的隐层是非常难以训练的。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 给出代码的运行log截图并提供心得体会文档描述对整个模型构建及训练过程的理解。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "代码中设计的网络 由输入层 $\\Rightarrow$ 卷积层1（relu激活） $\\Rightarrow$ 最大池化层1 $\\Rightarrow$ 卷积层2（relu激活） $\\Rightarrow$ 池化层2 $\\Rightarrow$ 成1维输入层 $\\Rightarrow$ 为10的全连接神经网络 $\\Rightarrow$ 分类器组成\n",
    "\n",
    "采用交叉熵损失+L2正则作为目标函数和0.6的dropout方式来训练网络\n",
    "且每次feed 100个数据，共训练1100次，在数据集为55000的情况下，共可以跑2epoch。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这个实例中，我们使用tensorflow来实现一个简单的手写数字识别的网络，并用这个网络来做个\n",
    "简单的识别示例。\n",
    "\n",
    "首先导入一些用到的库，其中关于slim的交易教程如下\n",
    "\n",
    "> [TensorFlow-Slim API 官方教程](https://blog.csdn.net/wanttifa/article/details/90208398)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:32:50.515650Z",
     "start_time": "2018-06-01T06:32:43.133728Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\Develop Kit\\anaconda3\\envs\\tf_gpu1.14\\lib\\site-packages\\tensorflow\\python\\framework\\dtypes.py:516: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_qint8 = np.dtype([(\"qint8\", np.int8, 1)])\n",
      "D:\\Develop Kit\\anaconda3\\envs\\tf_gpu1.14\\lib\\site-packages\\tensorflow\\python\\framework\\dtypes.py:517: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_quint8 = np.dtype([(\"quint8\", np.uint8, 1)])\n",
      "D:\\Develop Kit\\anaconda3\\envs\\tf_gpu1.14\\lib\\site-packages\\tensorflow\\python\\framework\\dtypes.py:518: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_qint16 = np.dtype([(\"qint16\", np.int16, 1)])\n",
      "D:\\Develop Kit\\anaconda3\\envs\\tf_gpu1.14\\lib\\site-packages\\tensorflow\\python\\framework\\dtypes.py:519: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_quint16 = np.dtype([(\"quint16\", np.uint16, 1)])\n",
      "D:\\Develop Kit\\anaconda3\\envs\\tf_gpu1.14\\lib\\site-packages\\tensorflow\\python\\framework\\dtypes.py:520: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_qint32 = np.dtype([(\"qint32\", np.int32, 1)])\n",
      "D:\\Develop Kit\\anaconda3\\envs\\tf_gpu1.14\\lib\\site-packages\\tensorflow\\python\\framework\\dtypes.py:525: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  np_resource = np.dtype([(\"resource\", np.ubyte, 1)])\n",
      "D:\\Develop Kit\\anaconda3\\envs\\tf_gpu1.14\\lib\\site-packages\\tensorboard\\compat\\tensorflow_stub\\dtypes.py:541: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_qint8 = np.dtype([(\"qint8\", np.int8, 1)])\n",
      "D:\\Develop Kit\\anaconda3\\envs\\tf_gpu1.14\\lib\\site-packages\\tensorboard\\compat\\tensorflow_stub\\dtypes.py:542: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_quint8 = np.dtype([(\"quint8\", np.uint8, 1)])\n",
      "D:\\Develop Kit\\anaconda3\\envs\\tf_gpu1.14\\lib\\site-packages\\tensorboard\\compat\\tensorflow_stub\\dtypes.py:543: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_qint16 = np.dtype([(\"qint16\", np.int16, 1)])\n",
      "D:\\Develop Kit\\anaconda3\\envs\\tf_gpu1.14\\lib\\site-packages\\tensorboard\\compat\\tensorflow_stub\\dtypes.py:544: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_quint16 = np.dtype([(\"quint16\", np.uint16, 1)])\n",
      "D:\\Develop Kit\\anaconda3\\envs\\tf_gpu1.14\\lib\\site-packages\\tensorboard\\compat\\tensorflow_stub\\dtypes.py:545: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_qint32 = np.dtype([(\"qint32\", np.int32, 1)])\n",
      "D:\\Develop Kit\\anaconda3\\envs\\tf_gpu1.14\\lib\\site-packages\\tensorboard\\compat\\tensorflow_stub\\dtypes.py:550: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  np_resource = np.dtype([(\"resource\", np.ubyte, 1)])\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "from tensorflow.examples.tutorials.mnist import input_data\n",
    "# TF-Slim 是 TensorFlow 中一个用来构建、训练、评估复杂模型的轻量化库。TF-Slim 模块可以和 TensorFlow 中其它API混合使用\n",
    "import tensorflow.contrib.slim as slim\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "tf.logging.set_verbosity(tf.logging.INFO) # 设置log里面的警告等级"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T05:39:48.304594Z",
     "start_time": "2018-06-01T04:55:17.674707Z"
    }
   },
   "source": [
    "先来看看数据长什么样子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:32:51.075054Z",
     "start_time": "2018-06-01T06:32:50.518290Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From <ipython-input-2-a34a30334354>:1: read_data_sets (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please use alternatives such as official/mnist/dataset.py from tensorflow/models.\n",
      "WARNING:tensorflow:From D:\\Develop Kit\\anaconda3\\envs\\tf_gpu1.14\\lib\\site-packages\\tensorflow\\contrib\\learn\\python\\learn\\datasets\\mnist.py:260: maybe_download (from tensorflow.contrib.learn.python.learn.datasets.base) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please write your own downloading logic.\n",
      "WARNING:tensorflow:From D:\\Develop Kit\\anaconda3\\envs\\tf_gpu1.14\\lib\\site-packages\\tensorflow\\contrib\\learn\\python\\learn\\datasets\\mnist.py:262: extract_images (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please use tf.data to implement this functionality.\n",
      "Extracting ./train-images-idx3-ubyte.gz\n",
      "WARNING:tensorflow:From D:\\Develop Kit\\anaconda3\\envs\\tf_gpu1.14\\lib\\site-packages\\tensorflow\\contrib\\learn\\python\\learn\\datasets\\mnist.py:267: extract_labels (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please use tf.data to implement this functionality.\n",
      "Extracting ./train-labels-idx1-ubyte.gz\n",
      "WARNING:tensorflow:From D:\\Develop Kit\\anaconda3\\envs\\tf_gpu1.14\\lib\\site-packages\\tensorflow\\contrib\\learn\\python\\learn\\datasets\\mnist.py:110: dense_to_one_hot (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please use tf.one_hot on tensors.\n",
      "Extracting ./t10k-images-idx3-ubyte.gz\n",
      "Extracting ./t10k-labels-idx1-ubyte.gz\n",
      "WARNING:tensorflow:From D:\\Develop Kit\\anaconda3\\envs\\tf_gpu1.14\\lib\\site-packages\\tensorflow\\contrib\\learn\\python\\learn\\datasets\\mnist.py:290: DataSet.__init__ (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please use alternatives such as official/mnist/dataset.py from tensorflow/models.\n",
      "(55000, 784)\n",
      "(55000, 10)\n",
      "(5000, 784)\n",
      "(5000, 10)\n",
      "(10000, 784)\n",
      "(10000, 10)\n"
     ]
    }
   ],
   "source": [
    "mnist = input_data.read_data_sets(\"./\", one_hot=True)\n",
    "\n",
    "print(mnist.train.images.shape)\n",
    "print(mnist.train.labels.shape)\n",
    "\n",
    "print(mnist.validation.images.shape)\n",
    "print(mnist.validation.labels.shape)\n",
    "\n",
    "print(mnist.test.images.shape)\n",
    "print(mnist.test.labels.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T05:49:40.128071Z",
     "start_time": "2018-06-01T05:49:40.123888Z"
    }
   },
   "source": [
    "可以看到images里面有数量不等的图片，每张图片是28x28长度的一个一维向量，\n",
    "所以用的时候需要先给它还原成28x28的二维图片。labels中则是图片对应的数字的值。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:32:51.695746Z",
     "start_time": "2018-06-01T06:32:51.077167Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAcwAAAG/CAYAAADVbefpAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjMsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+AADFEAAAgAElEQVR4nOzdd3hUxfoH8O+kEAJJaAGUGlpoiqBiV1DAQlNEwYoF4VJUuCp2f4hey1URKaKCqKAoKooURVSUYrmCWChCQpfeewkp8/vj7M57YDfJpGy25Pt5Hh/ezJ49O55szuy8O0VprUFERER5iwp2BYiIiMIBG0wiIiILbDCJiIgssMEkIiKywAaTiIjIAhtMIiIiC2wwiYiILIRsg6mU0kqpI0qp5yyP762UOux5XsNA1y/S8HqXvEJc82Ge47VSKibQ9Ys0fI+XvEi75ipUFy5QSmkAjbTWazw/Xwpg9imHlQdwg9b6s9yeR3b8XO9kANMBNAEQDWAlgIe01j/l9Tyyl9e1U0rdAeA9AH201m+7ylMArAcQq7XOKpmaRgZ/11spFQ1gGIC7ASQCWAPgcq31/ryeR3ZyuebjALQB0AjA3Vrr92yeFwpCtod5Kq31Qq11gvc/AJ0BHAbwdZCrFqkOw7mJVAVQCcB/AcxkzybwlFKVADwGYEWw61IKDANwEYALASQBuB3A8aDWKPL9BWAAgN+DXZGCCueb3x0ApmqtjwS7IpFIa30cQBoAKKWiAGTDaTgrA9gZxKqVBi8AGAWgR7ArEsk8H0wGAzhLa73RU7w8iFUqFbTWrwOAUirsPpiETQ/TTSlVDsANACYGuy6RTim1FM4n7hkA3tZas7EMIKXUeQDOBfBmsOtSCpwJIAvADUqp7UqpdKXUwGBXikJXuPYwuwPYDWB+sCsS6bTWLZRSZQF0A1Am2PWJZJ7v08YCuE9rnaOUCnaVIl0tABUApAKoB+c7tblKqXSt9bdBrRmFpLDsYcJJx07SoTpiKcJorY9rrT8C8KhS6qxg1yeCDQCwVGv9S7ArUkoc8/z7jNb6mNZ6KYApADoGsU4UwsKuwVRK1QbQFsCkIFelNIoFUD/YlYhg7QB086QHt8MZjDJcKTUmyPWKVEs9//KDN1kJx5Ts7QB+1lqvDXZFIplS6gI4749FcKaV3A+gOoBfg1mvCHcngLKunz8HMBXAhKDUJsJprdcqpRYCeEIpdT+cD4M9Adwc3JpFNqVUGTidNQUg1vOVzwmtdU5wa5a/sOthAugFDvYpCXEAXgewB8AWOGmqTlrrrUGtVQTTWu/XWm/3/gfgBICDWusDwa5bBLsZQF047/MvATyltZ4b3CpFvG/gpMMvAjDOE18W1BpZCuUGMwPAEqXUs+5CrXUTrbXPJ26l1F1Kqf2e54X8J5UQdNL11lrP11qfpbVO1FpX1lq30Vov8B7M610s/L7HvbTWbU9ZtGAonDlsGWAasTB8rrfWeovW+mrP/O76Wuu3vI/xPV4s/F3ztlprdcp/84DQv+Yhu9IPERFRKAnlHiYREVHIYINJRERkIc9Rsh2ibmS+toC+zfm0SLPNec0LrijXnNe74Hi9SxbvKSUvt2vOHiYREZEFNphEREQW2GASERFZYINJRERkgQ0mERGRBTaYREREFthgEhERWQjH3UqIiAInKtqE6eNbmXjFVWMBAF3u6G/KYuYuKbl6UdCxh0lERGSBDSYREZEFpmSJqNSLqVvbxOkvVDHx+rZvu44qAwDY36CMKUnmzpmFtn5KCxP/ePEbJr6l130mjv7h9xKtU37YwyQiIrLABpOIiMgCU7KUp+hmqQCAVf0rmbLV10v6JAeyEUIUnAX+x+6vZ8omvtrRxFUm/BKwehIVRkz9FADA308km7KT07Ciz6aLAQDVF+42ZdmBq1rE0/+UN3GVS+NNvLdxnImr/lCiVcoXe5hEREQW2MMkAEBM7Vom/nvoaSb+6Iq3AACt4nJMWY7rc1YOpNz7+atvxTWmpMYjk038zpxLTZy1eUvRKx1mosqWNXGdBbLd3tiaP5k4WjnXcOWJo6bswat6mTg7Ta4tFY6KlUE7K5+uDABY395/r7L+d3ebuHHfvwEAOcdXB7B2pUf5zf63+Tyt50YTZ79ZUrWxwx4mERGRBTaYREREFkIyJbvtgYtMrGRMCcrucX7Y10TKTv9FvnYvO3NRwOsWSda9dKGJV936uon9DeRxp2G/PFrBxIsO1/c57znlN5i4e8JBE2+ds9zEs5pXQmnhTcVumSKDoWbVnOz32LbLrwMAqOEyCCVu7Z+Fet2YlDomztrwT6HOEYnSxpxl4vXtx/s83nDenSZu1EvmAeb4HEmBcCwr1sRl8jguGNjDJCIissAGk4iIyEKRUrI7B0rqdH+LTBNPu3JMUU6LpmUW+y0/rrMAABWiZM7OztuPmHjrKPnfeXV7BwDAnh5Jpixr0+Yi1SvS3NhBRme607D+Rr6+vr+BKfn2quYm9jfa9acuN5m465syZ9M9enYWWheu0mFozdPOjherWr/u9/FGc+8xceP+aQCAnCMbTJk+9Ql5SB8n13X6laNN3PO9BwAAdZ7+uQBnixxrXrtA4s5jXY847+/638po2NS+K0xckGtPBZPUaZvf8gOf1TBxVWz0e0ywsIdJRERkgQ0mERGRhQKnZNPHS8pnVceRJo5Tsa6j4hAIJ7+Go1p0eVcs5ZPqLgAA3PZxW1O27xaOGgQAnHcmAKBfFUmXfnlUFitwj3xdftBJj2QMqWrK1r4kFzr12XImzl7pTOh2j1aOfUuOzXTlt7Y84qTza/43MlOE+kIZibnglpc9kVyrf7JkYYLU3jJ6OCfzRIFfK7P9OSae1kG+DmkeG2pjDEvWiavlXjXtutdMHK1kAQnviNhGd/1lynQOF7wLpOy2ZwMAZjaXryj+PCH3ieqTXX8PJVctK+xhEhERWShwD/ONyyeZ2N3j+++eRibeeSLR+nyfL3E+HdeZ6X+ZpPxsbidt/ksdPzSxd/7fBynzTNltH7Y18b6eshRcqRsMtGgZAKBv9/6mKHrbXhOfPJBnOwBgyyPS61zZRgaTXDO+j5xjpfPvnt4yvzNTLzGxezBR3cnOl/lZhal/GNjxiPQUq0U7PctjWsp6DX7QxOUyfy3Sax3+t8x1PbOM/E0e1hkmrvfpHgCla7HwKk+sN3GLMtKr7LCyi4lThzrXLpu9yhKTHefcsxOUZCIztWvQ4aFDJV4nW+xhEhERWWCDSUREZKHAKdnXet5g4idbyhzHal+kmTh7z17YSoX/OZe2Gs6U+O13ZO/F7VOcOYYDK24yZe70bOO+ko5MeaqUpWQ99OJlJs4vNVp2t6RMxh1IMXGZHYdNvG6YM5DnvdslZetdWg8AlmTI57NI362kb+qPPmXd0m40cblp/tOwKsb5k1Tx8X4fd8s+00mTj2j6rt/H2y65y8TVVqzK93yR5v6a3/ktPzhRvo6puJp7tJa0Dd3Ct58WvjUnIiIqQWwwiYiILBQ4JauXyLJRVWQAZEiMvstZKmmnd0d0BgAMHPaG32M/vE3mkD7+1HmBrVgYOHatXIO9TeRt4U3FVlkmqde+FTaYuOUsWbrqvDjnWPdo2MWuNOyTvV0jaiG7QJQWibHHTXzEVZ555bkmrvzUBgDAx/W/sTjjfJ+Sn1zXu+qLgZkPHeoO3OYsg3dZWdnl5eKl15u44vv/K/E6kUg8LXRHweaHPUwiIiILbDCJiIgshOQG0lTytvaUSfUr20gaWzaQ9t1UGpA0rLvcPRr29qn3mrj+D6VnROK48TI5vt9DznJ1k+rLkO5+P19t4gl15XrHwLW+YyHcObOfiRv9UjpTj/u7HvEpOzpDln5M0OuK78WiXL8vLn4Q8djDJCIishBRPczNj8v+nDmt8v5iuXq09KiyrnCW54v5fkluh5cq/vbD9Fd2annfTVcAADY9JssklqZepduRWr7LRscrWQx9Yt3vXY9IL+XB7c7gq6/myMLhmafLe3XNlePzfN3k3wu3xGQkOb3SQZ+y+D1FX8Y74xrnd7K7jyycf0Z12dPx0A3y+83atr3IrxdJosrK0oSX1Fzv8/j4nW1cPx32eTxUsIdJRERkgQ0mERGRhZBMycbUTzHxmt6nm3jsTePyfF7bsjK3L1rl/VmgVkyCice968zJHFD3koJUM6LU+FjSSTfWlAErZyRtBQD0qyL7VtaMln0d3Z+51r7QFAAQ/8MilHapb+0ycdPMgXke2/B9WUoyJ20tAKBelqSy1714oc9z3AZsudjElT+UrxW0v4MjVMxp1U08vvFkT5Tg/+B8RFesYOLrfllt4p6JowAAFaL8L1vYfMytJq7VnSlZtyjXNR1dY7bP4/N/PMPEDRC6g9XYwyQiIrLABpOIiMhC0FOyh288HwCw62xpu5+5foqJb0rcV4CzFa79b//dYABAKn4r1PMjQfx0SaNmTJfyJZ5r2re17O5y6FmZ5/b9mR+b+JKnnVTKX0tqm7JI35UkN9npa01c79G1eRyZ/7KSMUfzHvn629stTZycWTpHJSNWNs6uE1PwVOzOATLC/rp/zTNx3wpbXUflvYNM1UTf+Z/kyEqpnufjdb7OLKGaFA17mERERBbYYBIREVkosZSsatXcxBXHyGTfr1KcZcHyG9UKAF8ccVIty4/V8vv4rJfamjg6wxkjeMczshzZyekVUWZ7rN/ycBRTW65N1qbi2xjbvdl0gqzqhhvny4jaaQ2/AgCccY+MNq7zdOlMyRYnlUvONsuTzK2UnlGCtQlN+pAsVDLuQA0Auf+9RydXMfGmuxsDAJYNHlvkOhw4JpPzqxX5bJFl9xPHfco6rupq4jLz/jJxKI/uZg+TiIjIQkB7mBuHyRfpT90kg0NuTdxj4n+ynGWmVp2oZMru++geE5fbJgMeTp+3GwCQ/Xe639er4Gf+zurHXF82uz5xrs+U5ZdSpofuUky2vPtZegfeAMCsjdKrP/26lQF53QOv1DFxzpvOZ8PMRscC8lql1V03z/FbfuMap3cfPa/07S16quz9B0z80WZnCbu+FWT02sWP/Gri1s/K4us9EuYW6XWH7Wpm4hr3y6CfrCKdNfK8ccZk10/OUpBbDyaZkhpZxZcNCyT2MImIiCywwSQiIrIQ0JRsxdY7TexOw7b7W77szRzt7FPnngeYAv9zyQqy21xOm1YAgOsqTnCVyueDvTmyFBwWLUM4cg/w6fmCs9zUbwdTTFmg0rDupcNueFHShe59MqlooqtWNXGjuDV+j9n9RgoAIBFchs3t+LvOcpoZL8vcvpdP+6PI583Uzh2o2fzepiz1MbmvZW3cVOTXiCQxKfJ1TaKSpTWjVfgOsmQPk4iIyAIbTCIiIgsBTclW6S2jTxs+IEurNRgiKdcY/BOQ196X6syJuris/88EfZffZuJk+B91G+o23iIpD++IwBF/tDdlDVD0NJRx3pkmvObdBfK6FSVdmOP5/BWbnvcSYpS/A5c3MHGXcpL2PqxlzmXZ3eGxnFhJS/rQGSn+638k9XdZ2dyO9pWtZbPpc3+7xcRlpjoj+eu/L/cvjobN3fG3JU6NlV+A9/omfJJ06lNCHnuYREREFthgEhERWQhoSjZrm4zeazCkZEfy7WntmyxZeeKoiRPHVvB5PNzU/EGWA4sd5EwGHtTye1M24b5OJq6yQlJ5Md/LJsNe0c1STby1XbKJEzo5v7cfznzPlLlHw+a4PnOlzv6X8+8wGRFHhXPHsBl+y9dnyvWO/c7390j5a/Lj7SZWyxMBAPVGrTBlOltSstUOrSq5ikWA6FT5KuHBFP/v4ZvXdwAAJE351e/joYw9TCIiIgtB3w+zOF21/KCJp1V83RPJfMs7Vtxh4kqzF5dUtQLHNX/04qXXAzh5f8p+j442cQ7kU/Ownef4nKprhY9M3CpOjo3yfKZyP9/9Oavx1IEmbvayMw+NAyGKrkq0/+UaX9l2leun/SVTmQjQ7I0BJk55QeZ86yzn3VqQOd6UuxM1JXPXLt7/pgDpHzsL3lfX4ZeJYg+TiIjIAhtMIiIiCxGVkr0haamJy0U5e2emZ8oOAuXGVCzxOpWUin1OAACGzZB06/PV5XpkujaZe7banwCAHNfOc7kN5NmR7ew8MnaP7DzzzZiLTdxoAueklaQTOdHBrkLYeK5+SxPXhqT/Qnm/xUjVb/OlJq7xURqA8EyDs4dJRERkgQ0mERGRhbBPye4cIKnC6tEy8tW7QfTNzw8xZcmz/e+CEgmyNjkbsP7VpbYpa/hf39GwALCyrbNm1WVLe5iyXXv9L1PV8DUn0aoXy4jcKrnsJkOBNz5llonPGf5vAECDB303TicKhugfZDPzjjXPdj1yJJc4vLCHSUREZIENJhERkYWwTMmquDgTd+8nS8Edyjlh4o6LnN1R6rxVutKHWZu3mLjBrVv8HtMZTqo2CWtNWW77BnBEYXA8MeVWEzfp9arEsfLeRw437CYqSexhEhERWQjLHiZypN/z/szLTTz7r7YmrvMJB0JQ+Kr7f5IZeeD/LvR7TAMOviIqUexhEhERWWCDSUREZCEsU7I6Uwb3pDzBtBQREQUee5hEREQW2GASERFZUFpzph0REVF+2MMkIiKywAaTiIjIAhtMIiIiC2wwiYiILLDBJCIissAGk4iIyAIbTCIiIgtsMImIiCywwSQiIrLABpOIiMgCG0wiIiILbDCJiIgssMEkIiKywAaTiIjIAhtMIiIiC2wwiYiILLDBJCIissAGk4iIyAIbTCIiIgtsMImIiCywwSQiIrLABpOIiMhCyDaYSimtlDqilHrO8vj2SqnDSqkcpVT7QNcv0hTievf2XG+tlGoY6PpFokJc82Ge47VSKibQ9Ys0fI+XrEi8h4dsg+lxltb6Ce8PSqkrlFK/K6UOKqXWKaX6eh/TWn+ntU4A8E9QahoZTr3e45RSaZ438J3uA7XWEzzXm4rm1GveUim1RCl11PNvS+9jWuuhAJoHpZaR49Tr3UUptdxzo/5ZKdXM+xjf48Uiou7hod5gGkqpWADTALwFoAKAngBeVUqdFdSKRba/AAwA8HuwK1IaKKXKAJgO4AMAlQBMBDDdU07FTCnVCMBkAP0AVAQwE8AM9t4DIxLu4WHTYAKoDCAJwPvasRjASgDN8n4aFZbW+nWt9VwAx4Ndl1KiLYAYAK9prTO01qMAKABXBLVWkesqAAu11j9qrbMA/BdATQBtglutiBX29/CwaTC11jsAfATgLqVUtFLqQgB1AfwY3JoRFZvmAJZqrbWrbCmYhg0U5fnv1J/PCE51Ilsk3MPDpsH0+AjA/wHIALAQwBNa603BrRJRsUkAcOCUsgMAEoNQl9LgWwBtlFJtPWnvxwGUAVAuuNWKaGF9Dw+bBlMp1QTAxwB6wXlTNwfwsFKqU1ArRlR8DsNJWbklATgUhLpEPK31KgB3ABgDYBuAZAB/A9gczHpFqki4h4dNgwknTZKmtZ6jtc7RWqcB+BLANUGuF1FxWQGghVLKnSZs4SmnANBaT9Van6G1rgJgKJwU4eIgVytShf09PJwazD8ANPIMS1ZKqQYAOsMZyUkBoJQqo5QqC+d7nVilVFmlVDi9Z8LNPADZAO5XSsUppe71lH8fvCpFNqXUOZ7v06rCGb0509PzpOIX9vfwsLn5aa3XArgbwCgABwHMB/AZgAnBrFeE+wbAMQAXARjniS8Lao0imNb6BIDr4KSs9sN5v1/nKafAGAnnWqd5/u0T3OpErki4h6uTB+SFDqXUcThfDI/SWj9lcXw7OBc/DkBHrfUPAa5iRCnE9b4LwAgAZQE001qvC3AVI04hrvlQAA/AeY+X11pnB7iKEYXv8ZIViffwkG0wiYiIQknYpGSJiIiCiQ0mERGRhTzXTOwQdSPztQX0bc6nKv+jcsdrXnBFuea83gXH612yeE8pebldc/YwiYiILLDBJCIissAGk4iIyAIbTCIiIgtsMImIiCywwSQiIrLABpOIiMgCG0wiIiILbDCJiIgssMEkIiKykOfSeET+rB1+gYkHXT3bxF/dfCEAIGcp998ttAtaAADWD5KVudLbTDRxw3l3mrjBLX+WWLWIiiKmbm0T7z+/JgBgW2fZ5rX/2fNNPLhSuonP+PEuAEDOhvKmrOEw2W865+hR39c6/TQTZ23bXpRq+2APk4iIyAIbTCIiIgthn5LN6NTaxHv7HDbxH60n5/m8fpsvNfGPs88CANR/SzZUL+6ufLiLqVnDxGOufdfEHeKPmXji+R0BAFWWlly9IsH2wReZ+Pl73wEAXBl/xJRluvaaGHneFBOPQhOfc+24T85V40NJjWfv2VssdSWytXWIvBefuOcjE3dL2OlzbJSr75aDHBMvvWSCE1wix551fJCJ6w792edccR9nmzjrsoLVOT/sYRIREVkIqx6mii0DAEh/tZUp+7LLCBM3jI0zsXxG8e/NWgvl2D4LAAAtz+xlymp1Zw/Tbe2/6prY3askeypO3p/7epxt4gUPDTdxOVWmwOfd/Jh8kl888DUTfzKwlolHvdYdAFD1zV8KfP5IE3VWUxOnPRAPALi95a+m7L7Ki0zcbvgQE5/2mm9vhk4W3SzVxPn1KndlZ5h4Y1Y5E2cj1sTnlnEGBkUrGQT31z0jTdz6oPQ2Tx/u/H4uqbzWlM1BUsH+B/LBHiYREZEFNphEREQWwiolmza6JQAgvctYUxaFsibOgfZ5jlvfTW1N/Hbt+T6Pj2opAyqGV2ljYg6YAGpfvDnYVQh7656WNOyKXmNcj+Sdhn1zf30Tv/V+JxPXhJOCyqgiX0DEqmgT35q4zcStH30VAHA7HjBlkZ6edafAt/c9x8S/PiopvUM5TsrvgikPmbIFLRuauM1ti02cJtluysWqRxNM7E7Deq8zAFz+Wx8AQPWRcu+Onve73/Pt/pczt7vzgAWm7PFkmX+cHefzFPy4t4Hrp112FbfEHiYREZEFNphEREQWQjIl6x0NC0gaFgBWdPamsSTttC1blka6bJqkVepPc1IAcatltGv27j0mbvXxrSZe0voDAMDvx1JMmT6RWcjaR5bjnc8DAIysP9pVGuv/YPLLmxos32yf9XNmH0008WcPX2niml8WbqRmqudvaspjr5iyq1oNlsf/tdjnOeEqqqyT6lv1WgtTtqaLpMBH729k4k+HXQ0AaPCJpKejUyWlt7SB3H90F2ekZsxRmecXM3dJcVU7Inx+6Ruun6Q/NmBjVxPX6Pa39fmS33J+L9/vlImYj4/Je0nItK/l91uLKVkiIqKSxwaTiIjIQkimZLcNPNfE6V3cqUAnFTvhQB1T8nmfDiZu9NP/fM6VlctrZGT4phVnbpEUTvyh9Za1jWzHqjjX/MwyTMMWhIqRP621zzijY/8+d0xuhxvekdw7u0tKNm5L3unSlC9lBGKLuneaeMmFE0zsHT1bL0ZGJiatipzfaVQ5mfi+5UNnkY01rd80Za/ukzTdnPtkBHzCD773jOx0mfhebt9BEw/+ZR4A4O3tst7agblFqHQEct8n3LMWFqfXM3Eq9qCgEpdLavXH4/IerrLC9w6vlU9RsWEPk4iIyEJI9jD7951u4ijIx4UX9jQDAPzSVZZfUhvy/gI4OkmWRtp8zxkmfrjF5yb+44Qzjy3+KvYqC+qnDPnMlbgpt/586ZPRXpZv/Pu2vHuWg7ZebOIdnZxP6Nl7tlq/VvQPMoetzg9SPi3tdBP38LM0Wbhz9ypXDZe/bW/P8pW9jU3Zgq7NTBy93v+cP3823Sk903bxcwAAe6vK8ydVlKxU9v4D1ueNVJcv727ib8/4xMQT275t4ufQEray2jnzZ6s+K73++jFynZMflHv2EU+zofKejl8k7GESERFZYINJRERkISRTstkn7Y0m/euvnm8LAEjc4PtFPQAgSuZnZrdx9rjsPEa+le9XUfJV7lRvp7TrPNGWwlY5YjXptyLPx1/bLIOuynwdOXP5CmPH/bJryID+X+R5rDsNu76N6/1+lMsw2tp161kmXtP1dRN/edRZnm3Btc1NWdb6DYV6jRMVfPN7K4/L3rBMw54sYbA0KW9MlXR23wrpJk4f68ztbvZfWbpxx5Wys06Xe2XZ0l4VnWUMa8S418CTeFL9mSbu3PE+AEBWfOBysuxhEhERWWCDSUREZCEkU7K5Kbf9RJ6Pe9OwADD7g/F5HtttTUcTR3V3ltfLzu3gUmxAdW8a2//kprTZgVuGKhy4NyN+8X6Z99gu/qjPse7dcryjYYHiTcOqVpKGTIn1HQ26JlM27a2wLvxGNcfUlHTow0M+NPEW1xKZLwwdAABIWpfLVzf5vUb9FBN3vubX3A8kH9krV5v4/ZHXmLj/UClfda0nfX6tPC/qpK/hZPcdd/rV65HtF5p45gKZs99kmbOj0r9ekqX35jzFDaSJiIhKHBtMIiIiCyGZkl19rLr8UGGDCd+ZNAoA8OKO9qZs3kbZ7PXr80a5zhIPADiQc9yUtP7y3yZu8qCM/sw5cqSoVS616n4hadjSmNK+9H1Je/pLw7ot/uJME9fcU7hdR/KT1l8m858X5ztacM4RmcAfP31RQOoQSDlVJMXWvbzs/vLM7vNNnPShfSrWu4ThlsHnmbJH+3xs4psSSt/XDEVx7Fq5jpcWww44vTc6o/B3PSDLoUYtXWPihkfld10SXzCwh0lERGQhJHuYKwfKp2B8Jl+6nx7t9BpH1vjJlEXVkE/qOZ5epdvlo4eYOPUl97GUG/d8wsax3msmCx67B1ggqzT2K4Hd/3IGHvSvNNxVKgMUtmUfM/EDG515vnU+32HKivOqxdSra+L5V49wPeL79/Dj3oaun3YXYy2Cq2vSHyae1XcQACD2qP/5eHs7ye9m1kVjAQANYqS3/cWRiiZuOKOfidd0dZbcW7xXrjdgv4RhJNt7l/P30OPBb0zZ4ErpriPy7pt5NwcAgGav32fi2s957z/7TVl+9+4oFbi7O3uYREREFthgEhERWQiZlGxGp9Ym3nSTfH0blcv8P69o5WrztXTF2624HgBQ46XADK6INNHVq5m41S3LTJwUVdbn2LbTHjJxo9WFm+sW7g55snIJUWj7oMcAACAASURBVL7zxADglZ2Xy7GXelOfgUmBpg2UXUm8X1ucap9n8Nv2kQ1MWfkwTMnmLEszceonA0yc3mOsiRcNfR22vj5WBQBw3dt3m7I6Ly0xcZPGsh8mujr/rF4sKdn6pTglG1O3tomfenwiAOCacodMmXs+5d5smf/bdalzrSed8Z4paxgrf0cxMk6zUHJ04PqB7GESERFZYINJRERkISgp2agWTUx82jhnh5C3a79lytw7lPgb7/Todknffr5IlkZ6o8NEE09o/AEAoFcPSR8mfFI604dWkiuZ8O3aX/s8fNA1nzVxPT9n5efr7+R9WQ+/BOZFlPN1hY7O5zgAD212likrPzXMl3rTcm9o+G/5ez5v1UAT53Tch1Pt35lo4pTPpNy7w05tyFc37rG1eukqE/9nt7NJ9W1XyW4aPz9cpgCVD3/RjWWU9QtzPjBx41jnTfhPlqReO34gMxQajt1o4spbnNGznd+X39mqK2SD6cpXudLcIzxv7hz7ceUTPrzaxLVQvF/J8c5HRERkgQ0mERGRhRJLye7uKyvMz3nqFRNXMKMw/Y+GfXDbBSae/b2T5kodsd6UpW6TCcevXH6rHOvZreSmobNN2axPJO1IJ8sun3dqaVmmLLl22msceZyf038K/IIOB251loNb1SP/UaE//+QsBtIAkfm1RPJbrrT3W76PV/MtshJdpbKJW5Vzrt2So/UKebbwt3pogom9aVgA+O6Yk/J++rn7TVnKu/I78bdsXcPbZbGJ7vM7mXhO809NfMEAZxGKamPs7zm1ng/c/Yk9TCIiIgsB7WEeukl6h/57lcDKzEwAwIjtHUxZ2muyp1+FL/40cf3jzieW3BbZjZ7/l4mbfOJ8ofzXja+ZsmlX3mvi2G9+s/p/KC0Sh2/L8/H+f0jvvRZW5HEkAUDdx2WwyI6ZRTtXTK2aJl49UBah/vU277J8/ueCfnRINjFIfdcZCFM6FzIsPF1T+qadyh0GAAxaKNmyVJSu+8h7F7zjt/zlQbcDACp/WbgBbmu/ri8/yG0a9wxw/nhmjKlSqPMWN/YwiYiILLDBJCIishDQlOzuFjKQx52GnXZEvkh/t4fzZW/On3+bskTXwISCrDsfFS+v0fzsDQCAOBUr54rJe5m90iamdi0Tpyb84/eYWzc4e4/WvUfmRjGtl79LKsqefV80cr6ayF69Lt/nRTdtBABYfUeyKXvthndNfGW8e+9W/6lYr4kDrzVxzIoleRxJudnSobJPWczuWD9Hlg7RrlmqUa7+VtyeDH+HW0t5T/42PuglS+5dHO/8HX2ZnGrKsnfvKdJrFQV7mERERBbYYBIREVkosXmY7l1HHvmhh4lT/1xcpPNGJ8voqXLT5DU+rv+VJ2IaNjfbO0rqY0a1GSZ27wCz77gz/zLqhCw3pmJlzqbOPBHIKoasRm87o4qHdWxpyoZWlRHddyVtMnH0DOeLhWVHJQWem5blnWXXbk3Me9Sy24wjMr/4oe9uMnGT/8loZm6YXjgZlfxvQl1afbBHNpdvVeNHE2/4t/Nv/ReamTL312z50a6N6A9ky5zvpmWce9HObpKSrTI+75G47tkZiVOKd94xe5hEREQW2GASERFZCGhKNnmppDP25Rwz8eKOsphA67cGAwCa/p+sZp+9Y6ff88XUrAEAOHKWTOQePPIjE3cqd8DE3hTU6/tlw9z4hat8Hidf2a6NuL9q4knVpsvjjabKxr2NBkXmUmv5yVq3AQAwZ9QlpmzwMLkW7lHhvZKcHXng/bcIjmpJgb++10kHL7hbdu9J/U2WiuR7nIrbN9+dLT/0kpTs0ksmAAC2TpfRssN3tjPx7IWt8jzvtOulTXAvufdHhtOnqzpZFqXJ7319w5PfmHjOlKR8ji4Y9jCJiIgsBLSH6f7C9bKGsjfaX/1Hmzi985sAgBVXyoJ3g1f39Hu+yU0nAzj507t7MJH7k4d30fZV98mX0OrQXyBRdq9csbVZkgFoEBPvc+wxV8+m3DZ+zvKq/I4MQPi//vKJul/VeSZuGlu0eXvuLMn7I68xcfI472svL9L5yY53MFylUrwyZMPX1pr4157yvj4/zlnitJbr3jHcNShoeE+J/YmCa768604++1ALp+zoUes6jl95sYnrYJn182zwzkdERGSBDSYREZGFEpuHWXmVzLN5c7+sTN+s7GYAQNuyklr9tvlnuZylrE/JmwfqmnjEl51N3OgpZ681dZxp2NwkfPqriXucJinzPx8ba+L/7G4CAPhs3BWmrGYB9qYrTda2Pm7iRxveLOV3ngYAuOpq2dli+OnydUXzSbI9g/Kz7mCDD2UpsOS/C7cbBBWddzBcpZWHg1yT4HEPyHzx6u4mThtQFQDQt91cUza4sv08zN7/XG7ixXPOMHH9Cd4lOzdbn6vOjcWbhnVjD5OIiMgCG0wiIiILJZaSLT9V0n+zpspSXl+nnAUA6P9iRb/Pe+HsL0z886GGAICZc843ZfUelxRVA0jMOWgFU320pFmvGt3S5/FqYBq2ILLXrDdxypNOnPakPN4Z55i4HvJOs3J3mNDgXjKSgOx0GTHbcLATf4/ypux7tPZ5Tu4OmqiO616T5e/QIOI7gIiIyAIbTCIiIgsllpLNTdYGZxRUvZv8b2A8DvVdPzmJ1vxSWERExW1tpjM6Nnq/TKJnurx0YQ+TiIjIQtB7mEREoSrlSclmDXjSu9D+Wv8HU8RjD5OIiMgCG0wiIiILbDCJiIgssMEkIiKywAaTiIjIgtJaB7sOREREIY89TCIiIgtsMImIiCywwSQiIrLABpOIiMgCG0wiIiILbDCJiIgssMEkIiKywAaTiIjIAhtMIiIiC2wwiYiILLDBJCIissAGk4iIyAIbTCIiIgtsMImIiCywwSQiIrLABpOIiMgCG0wiIiILbDCJiIgssMEkIiKywAaTiIjIAhtMIiIiCyHbYCqltFLqiFLqOcvjh3mO10qpmEDXL9IU4nr3Vkod9jyvYaDrF4l4zUsWr3fJi7RrrrTWwa6DX0opDaCR1nqNq6wlgAkAmgJYCaC31vpP1+MpANYDiNVaZ5VohcPcqddbKZUMYDqAJgCi4Vzvh7TWP+X1PLKXy3t8HIA2ABoBuFtr/Z7N8yh/ft7jqQBeBnARnPf4YgD3a63T8noe2fNzzS8FMPuUw8oDuEFr/VluzwsVIdvDPJVSqgycG/gHACoBmAhguqecit9hAHcDqArnev8XwEz23gPuLwADAPwe7IqUAhUBzADQGEB1AIvg3GMoQLTWC7XWCd7/AHSGc6/5OshVsxI2DSaAtgBiALymtc7QWo8CoABcEdRaRSit9XGtdZrWOgfOdc6G03BWDm7NIpvW+nWt9VwAx4Ndl0intV6ktZ6gtd6rtc4EMAJAY6VUlWDXrRS5A8BUrfWRYFfERjg1mM0BLNUn55CXesopQJRSS+HcvGcAeFtrvTPIVSIKlMsAbNda7wl2RUoDpVQ5ADfAyRaGhXBKryUAOHBK2QEAiUGoS6mhtW6hlCoLoBsApr8pIimlagF4HcADwa5LKdIdwG4A84NdEVvh1GAeBpB0SlkSgENBqEuporU+DuAjpdRKpdSfWuu/gl0nouKilKoK4BsAY7XWHwW7PqXIHQAmnZI1DGnhlJJdAaCFUkq5ylp4yqlkxAKoH+xKEBUXpVQlOI3lDK211dQHKjqlVG0441ImBbkqBRJODeY8OANP7ldKxSml7vWUfx+8KkUupdQFSqlLlFJllFLxSqlH4Iwk/DXYdYtknutdFs5Aq1ilVFmlVDj9nYYNpVQSgDkAftJaPxrs+pQytwP4WWu9NtgVKYiw+UPUWp8AcB2AXgD2w5nycJ2nnIpfHJzvdPYA2AKgI4BOWuutQa1V5PsGwDE4cwPHeeLLglqjyNUNQGsAd3kmy3v/qxPsipUCvRBGg328QrnBzACwRCn1rLdAa/2H1vocrXW81vpsrfUf3seUUkPhzGHLABA2OfEQctL11lrP11qfpbVO1FpX1lq30Vov8B6slLpLKbXf87ycINU53Pl7j7fVWqtT/psH8JoXg1Pf4xM917e8e26g1vofgNe7mPi8xwFAa91Eaz3h1IND/ZqH7Eo/REREoSSUe5hEREQhgw0mERGRhTznYXaIupH52gL6NudTlf9RueM1L7iiXHNe74Lj9S5ZvKeUvNyuOXuYREREFthgEhERWWCDSUREZIENJhERkQU2mERERBbYYBIREVlgg0lERGSBDSYREZEFNphEREQW2GASERFZyHNpPIpsWe3OMfGe5nEmPlZNVtLSDY8AAB456xtT1rvCdhN/fVSeN2RcbwBAjZd+Lv7KlhKrJ54NAEhrP96UXXHvABOXm8b9u4mChT1MIiIiC2wwiYiILIROSlbJ4vA7+19o4v73fWHivhW2Wp9u3IEaAIAvul5gynI2bDaxzjxRqGpGggO3Odfk+xdHmbI4JW+FHPhubhAF+f1kujYdbxd/1MQ/3j8cAHBR9IOmrNYLTM8WiHauc45rs/kt7eThRtNKukLhJ6ZeXQDApm41Tdmh1CwTN07dYuKZjWcAAFJn9TNlteZIPyLpD/n6QR923uvZu3aZMhUjfzdb7z/PxFnxzr91Xlkiz8/IKOD/CYUa9jCJiIgsBL+HGRUNANj0xPmmaFm/MX4PzdDZAICtWfJJraxr17Jq0eVM3DvJ6U32njfVlI3c19DEczufYeKsDf8UpuZh6+B1hwEAsSralLl7lf9kHTPxE5u7+jz/11X1TRxbXnrqP178BgDgouv+MmWbXpVBQfyEXTgNmkpmRcXxevqzffBFJv5tyGgAJ/fSc+M9Ir3zm1LW2f/zPj50OgDgnX93M2VbL5Vb6LI7Rvo8p8u8PiZWP/2Zb30otLGHSUREZIENJhERkYWgp2S3DHFSsbmnYeXL+rM+HAQAqP/wL6YsumkjE696LNHEy69wUizuwSyDKq2RE8+S8Lu29QAA2bv3FLT6YSmljzPoYcDXl5my5XtPM3GlQXJsdvpan+enYq/f857/5r8BAOld3jBlLR+8z8S1nucAoML4qokMfLs2oYOJs0t5Sja6YT0TTxw0wvWI/W1t2uFqAIDuCbvzPbZn4jbn37fHmrIoV5/Dncj9I8Mpjz5w3O/j4WrH/ZL6Pnju8TyOLB6xcc79f/kl7/p9vHPNc/yWBwp7mERERBbYYBIREVkISkrWPXepzMV5p0HP+FxSeo1cqViv7JWr5fFeUn5pXyev+NIj40xZ27KZJnanZ+cmnukEpSQlm71vHwDgj/Ey37XiWknvZaf/XqjzRh/x/fzVvGOaiQ88X6jTEvm1tePpJm5axve9d8WyniYu/2yS33PEbtsPAJhQo6Ipy6hSxsQDXvrUxN0SduZZn+UnZKT5kAed5QzLLY+spQyPXCDzrle2Ge/z+MkpavskdH7Pc5d8cLC29XmLG3uYREREFthgEhERWQhKSja6Ti0TLz7nI5/HR++XifFN3txn4uwCvEbyOCd9O63PuaasbQ3flG5pVuXtwF+PzsmyiMFk1MrjSKKCueT2JX7Lt2U7C2/sWFbdlEVf4/8c1X9z0q87zpVFPC5pv8zE+aVh3WYdbGniSN1VptGA9Sa+PlEWcFh/Zx0AQEYlSZ4q3xU2c5WTLAugrGz/ls/jTb6SHXuaPuya7YB9PscGEnuYREREFoLSw9zQs4ZP2WEtg06mPH+1iSv8/b8ivda6O1NM/NNM+dR3cZx8Elrd16lP/adkUWadJfM/KXcZ17Q28Z0d5vk8/sXOVq6fdvk8TlRYX/52lolf6rLQxHViEgAAK2/xP7f7JHc5/7iXiczU7lyW9Cl2e3qul376kCmbd+MrJn48WXqmbXsMBAAkfFK0+1eoyd5/QH5wxbWf3eznaHuHe8gmGWgv4ZpM5z7c9GWZ++0dtBgM7GESERFZYINJRERkocRSstFVKpv4kTs+8Xl86iFZ5qrC5OJLY2SvkHmAd8zpa+I1XWV3gpW9XgcAdPrMNZHzt+XFVodIEJ0k89h23NzcxP8aPN3E3h1iNrh2O9nzsvxeyzIlS8Uotf8iE59dpbeJl138HoCCzQPMdA1QmXGkkolHrpfNSKNGJgMAGnwl96dLyz9g4lVdXjfx1g5OWjfV91ZHfmzr7H9/4mGbOwPwv0RnMLCHSUREZIENJhERkYUSS8mqsmVNfGui/dym4pS0yvW/67svMtL6SR1T7ymBCoWQqJbNTLy1rSwTdrCxM0qtz8XzTdmQKj/kchZnN+/2X0maKnXmolyOJSo+9YdJSq9t84FFOlfF37abOH7detcj630PzsWZqZsAAKV7Pxl7q9u9beIcVz9uySJnN6qGCI1lS9nDJCIissAGk4iIyELQN5D2+mFfE9dP+4NWj0gVc7psEH3HfGdJvKvKSeopFpI6dU/iLohLHnKWr0r9eHGhnk9UWO7R8AkrinaugixZ0jh1i9/yZenOjhqp2O73cTpZDrQrLtzyeiWBPUwiIiILJdbDXHdPSp6PL58ig06q4+cA16b00ZVkHmW38t5lpsr4P7iQzKfBnIIsk08n8VxE9/6Ahe3xU2Bktj/HxHMay367v2TEmrjxWGffyBDrIIWUY9ee5/rJ/0L62ZWdPYzXfSgL259T9x8TDz79WznWM+iwzzv3mrLa/ynetoQ9TCIiIgtsMImIiCyUWEr2eF3/Sx9RCdkmy9Kdv+QWAECrajJgYeH3Z5o4fofyefqx6pJceqb7FBN3T9ht4o6PzwMAfIW2pixxSmTt1hBw2rn27oEP7mXbVj7fwMSp/5IdHCjwohITAQDPj5M0rDtdvuCwDFzUfxRx5FEYiK5ezcSHLnKWwDxWWfpgUdfv9nmO28Tmr7l+ivN7zKor3/Rb7tV7YwcTL/na+Vov5dU/TZn94oh22MMkIiKywAaTiIjIQsjMw6TAcm+6WrWrE7u3fK2HX6zP9f7o8008+t1yJv7+zI8BAPP7NJKDP3GN8OTo2aIrU9xJJsqLe5elwx9WAAC0ivOfLn9nfhsTN4JsVh9JMq8818SJT20w8bT6zmbd7tHd+e8WE5vP45Jy3fVAHf8H/G+pCet4ZlcE8i+EPUwiIiILbDCJiIgsBD0luy3bmeCb9E9BFqQKjPJrincif6TK2ibLfSVcLeUPLr4EAPBVky9M2QV9ZBJx8lv2aV+iULCpt4x8/e2MkT6P/2d3CxM3HbHDxMG/mwXGxmukyZhTf46JJx+qCQDYny1f0UzfepaJd/5Q0+dco3q/ZeJ28fJ1TevfbzZx5c7pnig0lktlD5OIiMhC0HuYiVHOoJCMJBkcEl+M549uKgNQbuszJ48jgboT15k4XD8hRleqZGJ9Qua+5hw5EvDX/npBKwDAiJtkOapuA2XvzIVvlfV5DlEo8M6xBIAdk2uY+LOzXnYd5WSgRrk2ipjz0qUmrrAu8uccV1wpc7RTv+pn4qZDnJ5g9v4DpqwMNpq4liv2+uuWuia+rOzqYq1noLCHSUREZIENJhERkYUSS8kmrnANqLlKwgTlLIl04SDZQ3HlpOJ73ZrvbTXxA5X8d/ubThwIAKi/K3z3cYypXQsA0Gy6LHc3a/qFJq4zrPhW7VdxsozVP0Nk54aHO37hc2ydMu7lsWoVWx2Itg++yMRl2sv7bHizTwAAOTr//sBzGzoBAIbVk/eue56lvx19fugpcxErrIj8NKxb8rhfXLGUF+cM69gPKud/UJCwh0lERGSBDSYREZGFEkvJ1p6yQX54wPfxM8vJQm0rcVqRX2/di0468pOar7pKJZU4/kBtEzccsQYAkJ0VrmNjgQPnOfOcXqw+w5Q9fs9PJj4n+d8mbvz2QevzrruxIgAgs5KkqZ5tP9XEPRIk1RsF704bYuyzN5i4AkpX+oqK36GeF5j4tyGj/R7j3UEkU2fmez7vnGH3riPu5e4O5Bw3cbtXhgAATlvBDe6LwrvLSY1Y35GzABBzPHSXf2QPk4iIyAIbTCIiIgsllpLVronzI/c1NPGgSk469ObEf0zZc5M6mrjxK0dNnLN0VZ6vcfhG2UXjj9tGAADilf807IzuMsIue1d4TJrNS/ktxwAA/9l9hil7Mnm5idOuH2viqOu9qVPJPXnTqaeW2z4OADs9yxxePP1BU5Y69Q8T+38WqRj5M4wrz43W87Ktg3xtkttuGN6Uav67Zfg+59Tn/d/2diau+Y2zCTv33Cka72bT3RK+dJWGR98tPGpJREQUZCXWw3QvmTS3s/SCMMv5x9vTBIDV7d428fvnyQCg/06RASRet17/vcQVhps4XpXzOXb0B9eauNbKCPvi3rMv3IIHZO7llY9JT/7zJh+b2Dv31d1rdPPXm5x8qJopuyFB5rY2/3qAietOc57X6EvZC5C9yvxF1ZO9/v686B2fx90DT2p8FfTVLIPCuy/lzecsKtHXHVFjoYl/mJkAABh9SVtTlrV9x6lPIUvuvTPd7/GYw6Hbh2cPk4iIyAIbTCIiIgtBye9kbZABPh+O9KyTN0ged6dnb0+UvRdv7zMmnzNLGva9g86OA5/d0MaU1Vr5q88zIk3M3CXyw1wJu3aRC7z1ZmdgyaJLZSDQDWk3mXj3LFnCTnnGP9SYLAOuJp4lqe3U738rcp1Lvb2y19+Zk+4HAJx7mVzvzS/LjjsJX0T+e9ifzGbOzhZDq+W945CNq/+Wr3Z2zPfs0+j6duLRWz8xcc/EbSa+PP4wAGB0HPfNLQ7uwVWTDpxp4tjvlvg7PCSwh0lERGSBDSYREZGFoA+5qzLeWf3+m/eSTdl3KS1NvOpeGZ15yXl/AwB+XNTM77majNtn4pz09QAAnZlWfJUNY2VnyujC+jOdf2+CzEWNgaTJT3PFXu5xazHf7y32+pVm2XvketZ7zPl72ON6PB4lOzI0FMVuc9LWl/xxqyn7sdVkv8duy3bmJHd4f4gpazhOlt6M2ypp1tqZvsuzTXmzlYk/Liejzg+e43zNk3gwvUB1p/yNX3mxietgWRBrkjf2MImIiCywwSQiIrIQ9JSsl86UJcGyV68zcaNBEnunCDfKZdeL0J3uSkRFkb3G+Yqlcmcp64rWeT4nBbLZcUH2IcretctvebmNm5zHC3Au8rWlvW9ZwlcJJV+RQmAPk4iIyELI9DCJiCjyRR13Jr0O3yNLpFZ+95fcDg8p7GESERFZYINJRERkgSlZIiIqMQ0edAZtzkd8kGtScOxhEhERWWCDSUREZEFpzS1+iYiI8sMeJhERkQU2mERERBbYYBIREVlgg0lERGSBDSYREZEFNphEREQW2GASERFZYINJRERkgQ0mERGRBTaYREREFthgEhERWWCDSUREZIENJhERkQU2mERERBbYYBIREVlgg0lERGSBDSYREZEFNphEREQW2GASERFZYINJRERkgQ0mERGRBTaYREREFkK2wVRKaaXUEaXUc5bHD/Mcr5VSMYGuX6QpxPXurZQ67Hlew0DXLxLxmpcsXu+SF3H3ca11SP4HQANoeEpZSwBLABz1/NvylMdTPM+LCXb9w+2/U683gFQA0wHsArAXwBwAjW1+T/yvcNfcU9YFwHIAhwH8DKAZr3lAr3c0gP8A2ArgEIA/AFTk9Q7oNQ/b+3jI9jBPpZQqA+cG/gGASgAmApjuKafiVxHADACNAVQHsAjO9acAUUo1AjAZQD84138mgBkh+Uk7cgwDcBGACwEkAbgdwPGg1iiChft9PGwaTABtAcQAeE1rnaG1HgVAAbgiqLWKUFrrRVrrCVrrvVrrTAAjADRWSlUJdt0i2FUAFmqtf9RaZwH4L4CaANoEt1qRSSlVCcBgAH201hu1Y7nWmg1m4LRFGN/Hw6nBbA5gqfb02T2Wesop8C4DsF1rvSfYFYlgyvPfqT+fEZzqRLwzAWQBuEEptV0pla6UGhjsSkW4sL6Ph1ODmQDgwCllBwAkBqEupYpSqhaA1wE8EOy6RLhvAbRRSrX1pKgeB1AGQLngViti1QJQAc739fUA3ADgaaVUh6DWKrKF9X08nBrMw3C+Y3BLgvNFPQWIUqoqgG8AjNVafxTs+kQyrfUqAHcAGANgG4BkAH8D2BzMekWwY55/n9FaH9NaLwUwBUDHINYp0oX1fTycGswVAFoopdwpqxaecgoAz3c83wCYobW2GhZORaO1nqq1PkNrXQXAUAB1ASwOcrUi1VLPvzrPo6g4hfV9PJwazHkAsgHcr5SKU0rd6yn/PnhVilxKqSQ4U0l+0lo/Guz6lBZKqXOUUtGenv1bAGZ6ep5UzLTWawEsBPCE557SFEBPALOCW7OINg9hfB8PmwZTa30CwHUAegHYD+BuANd5yqn4dQPQGsBdnsnb3v/qBLtiEW4knPd3muffPsGtTsS7GU4vfg+ALwE8pbWeG9wqRa5wv4+rkwcrhQ6l1HEAGQBGaa2fsjh+KJxBKXEAymutswNcxYhSiOt9F5ypJmXhTK5fF+AqRhxe85LF613yIu0+HrINJhERUSgJm5QsERFRMLHBJCIispDnGpUdom5kvraAvs35VOV/VO54zQuuKNec17vgeL1LFu8pJS+3a84eJhERkQU2mERERBbYYBIREVlgg0lERGSBDSYREZEFNphEREQW2GASERFZyHMeJpVSUdESntHI5+G03hVNXHmpTFeq/sM2AEDWug2BqxtRkKwefT4AIKpKhimrPVFuoWXm/FbidaKSxR4mERGRBTaYREREFsIyJRvdvLGJN1xfxcTndlxu4kl1FwAAMi12h2k3sD8AIP6LRcVVxbCT2f4cEx97cL+JF7SYnOfzom6QlOziDGcFrkfu72/Kys4qvdeUwlPOpa1MfPaoP0w8JXkEACApqqwpO7NMLxPXXVhOznH0aCCrGBE2PnOhiWv9IGnuuI17TRxqX++wh0lERGSBDSYREZGFsErJHrzlAgBAp0fnAAmBNQAAEhZJREFUmbJpVZb5PTZTO58FcpCT73nfeG0kAGBImqRXsleuLmw1Q15UYiIA4OCnVU3Zx81Gmrh6dLzPczqvutbE63dKGjwx4ZiJ/3f2RwCAkaNHm7LH5rc3cc6hQ0WpNlHApI89z8T/bf+xibuX3+c6qixOtezCSSbu1PR2eWDJimKtXzg6csP5Jo7vv9XE99WZCwC4ptwSU7ayV6aJ9+fIdZ6+72wAwPJz8r+PlwT2MImIiCyEZA8zqqx8wlj7tHwBv+L2MQDseo0FkRpbBgCwclAlKetXrC8RUsp/FQcAmFJPBvS0/GawiWvMlnmYFeasBACoo9tNWb2szXIy15zNS2f1BAAsPEs+oa979AwTpzzxS1GrHjFUXJzEjeuZeNPTzvVcfkHeg61yU29ObxM3e3yLibO273ACza0RoyvJ3/mWXk0BAN91esmUpcSU83lObkbvry/n3XvYxFlFqWAYi6lZw8Rdhn5v4sGV//ZztPTXGsdGu8qlt9mk2kIAwDOLrzBl6+5MMXH2irTCV7YQ2MMkIiKywAaTiIjIQuikZJXM53OnYZfdPsp1UMHb92af3Oe3/O8eo33KXrj8UxO/e15neWCR/4FF4erVul8AAM75+CFTlvrg//wem+8s1hw5ovzwCgCAHe/KQKCcaJ9nlD6etLV7mcEbPp5n4l5JP/s8JbOQmdP0K8fJD1dKeMGwewEAyeOYFk8blWLi9CvGeCL7NOzcY5JOHzv9GhPXW196r+2O+y4CAFzU63dT5j8NK9ZnHTfxsozTTVwlWlLbF3q+nRte40dT1mRQCxOn9pXzRVevBgDI3rGzADUvGPYwiYiILLDBJCIishD0lKx3Gap1rq7131eMyuVox9TDp5n4yR+7mbj2DGn/46c7S7I1hKQaVavmcpIevuftliBd+VH1y5s4MUJXd0tao/I/qABi5jrzqj46eFaxnjfc5VzspJBmTXk732OP6hMAgDWZ/nPZ43a1MXGLBGe08gXxa01Z01g5NlbJOa4Z4KS0fp8uqa9Apq5CjXu5u+EXfJrHkblr9Jmz5GPqREkZ1ltSetOw++6Upe0WP+p8xVWQGQz3DPq3id3LksbUTzHxudOc+fCPJ/9pym5u/auJPxp3vk/54vtlmc+ohbK0YXFgD5OIiMgCG0wiIiILwUnJukbEelOxf18xLpeDRZe0rgCAnKdkSbfUn7hpa0Fd++LDAIADzWSEa9XcDi6AY9c6y4v1rygp9XHuoZoRTsXIn5M+u6mJu7/1TZ7Pe3lPMxN/8aozQbvSe7ml+mQE8gY4SxROveoqUxb3yDYTz2w8w8RDqzoprdShkkZLHRCZKdmdA5wRm1MfkcUIyikZZVktOu8Rsfty5Bq3e2WIiRuNdlJ+Oif/HZAilXc0LCBpWEDS/7mN7j57kSwbWKObM3o2Hv6/63LvUDJ7s/O38WTyUlP2fHWJh3XyTbnOfmeNiV9vlOq/QoXEHiYREZGFEuth5rbcXX4DfH7NkFEM+gpnqS+FLbkdThaqjXXm/VUr5vPmxDqZgzgVm8+RkcO9zNq296qbeNG57+X5vMbf9TFxk+cPmrhSmv0gkuiKzrzXzH/L/oHfuHqVpcmu/tJz/uDh4QAKtsTd18fk2CET7zVx7ZG+c2RLm20PSq9y1iDptedA5qN6e5Yzjsjfw+jBPU1ca+Eq1/Ps7Vue7DynpTzL3Yv1N8ioTfweEz8xROpe4+Wi/y7ZwyQiIrLABpOIiMhCiaVkddMGJj55uTtfTef+y8QNxkmXOwp/+jucQsTWrpn5HxRhclJkd4ZF507ye8zhnAwAwDkzZN5Zk1GSNspOW+PzHBvbJznzkX8988N8j12Z6fxuyuyNnLUK9/eSNOwvT8o9JcaVKrQ1tl0HE9feyDSs22U3yb6V1aP9X9sfjjlfuY3tf6Mpi5u72MSF3V+q0Tu7nOA239cCgNUnZE7+PRXWAQDKKmnWsmQ6fbFgD5OIiMgCG0wiIiILJZaS3dKugomj/LTT045UNnGjMa7UXoB2CnHXwd8cIl28q8ZFrOimsgPHgrbetFi8KUteGpkbFkclJgIAun34g9/HR++T6/LJC85c1EaTZZnGws7ki2opczbvT/0uz2O7r+lk4mP/5yyJlzI/vJdy0xfKsotf/OdlE8cUYLeRjqu6yvPudv7QszZttX5+ZntZeu1wzTJ+j0n+xZnjmp2+1u/j4SA6KQkAkBSzP99jB0x3Ni5vMNf/rkeFts25jhc/fb8pqrRKdjnZ21TSs/cM9f2qr0e3+Sb+39NFH73PHiYREZEFNphEREQWApqSjaldy8RX3yKpIH+TTR/5Xia5pi4KzPYgm5+S2F0Hbyr2jg3tTVmlL2Xz09K7EFb+MqslmLhWjBN3XX21KavwmSxdFUnJ2S19zwQA3JU0z5R5R8MCwEfDZbm6ypOLlgbdf7uMBn3n2VdNnBrrPx1onjeijonj50fGljs6Rj7j57fEnVuntC4mjrnTdb6jRwAAh3q0NmXl++S9MMoTKe+ZuG1Z/yPD/7P7DADAR1+0NWUpz8toU52RcepTQs7mSTUBANOqzfX7eLtlcs9ukMsG9EWVfdBZ1KPK+Fz+hppe6L/cw73LSVe0zuNIO+xhEhERWQhoD3PvpdLD/E/1aX6P6bDc2Ziy6cOydFJx9ug2fNzCxO+0fC/PY9e+2cTEFQ+G9+CIQMroJJ/U+r061cSZ2vnNHX9MlohTGdtLrmIl6FDDLJ+ys2cPMnHqu0V7/6S/eZ6Jp189Qs6bT6/ylwyZZ5m4eLOJfWsbnjZ0KZv/QR4918nC/6qLDFzZcrcMHGp1qzOocGbtscVQO/Fk8nLn33uWm7Krv73bxFE/huac8o3PSI9tWesxnkj6VbOPJpq4/NXrSqpaVvwNJm0x/j4T1wGXxiMiIioRbDCJiIgsBDQlu6fr0XyP2bTZ2dMv9eD6gNTh4RayF+G5cf6Tvb3/uRwAUOVrWaKsNAz0ialb28T/9JD46pslnVitzEGc6p4KI02cFCUpMu8wqrU3yDzM+rGyM03UfN+96yJJufWFm+cVnVzFxFtvaQwAmH61DO5pGmt/3icf6Gvi+C2RMdDHLfag/QTpYbVnmnjtn3KNLyor94RKUfEgEdXskIn9Dc4csUGWECyDjSVSp1Opc5qbeNADn5rYX32LG3uYREREFthgEhERWQhoSvbxll+b2N8IJgBI7f1bQF774Gxnd5ReSUtcpf7r8Pc7The/yq7IHRnrXcoNAFa93BQA8GsnGX1ZKcp+9CFcu0FkuZLXh3JOOOfv+bopO3yjzDfruPx2Ex+d44ykPW3Ur6ZMRcsIz+PtZSTjodrO2zR5XGj/fm64SZbhWjy1sTywy9mZ5MCVTU3Rzutkea/bmkvq9PFkb7rQPg3bbXVnE5f/doWJA5+gKnldutuPdGwSG+eKD7seyTsNm+OaMbwmU96/DT3ni0Lkrpv514UTTex9/wzfc4YpK3enzDsN1sjrtIHy++uZuM3n8V+Oy++9/iRZ8rA46sseJhERkQU2mERERBYCmpLN1tIeB2oEU3RF2QVlzZt1Tbyixbt5vm6zT2RCa8Pcll0Kc/oiSWs2Gy27vsw47Q0AwKSDsqn38BWyLGDsj0km/m3IaJ/zLjguk+cfHyajMuMOOOnZ+PslDfLvut/K81p8IifxrCfR7LR7TVFWRUnvTrtKXrf7T/0AAMnjfKoSNAnrff90nkxeauJPZsmCDeszqgIAHqnyfUDqsn6P7PRT64hviory12juPSbWR+R3695w+/NbnZHL7lRvbqKVc+8buktGdJbZKosnhNNCEh9ObmfimlsCv7l2TIos6ZhZoxIAYP8TMuMiveVbJvZ3d9+TLct1Zq3bUKx1Yw+TiIjIQonth1mc3PvRVX92tYmn1ZngOsr3s8B3x2TgS+Pxe00cSXMuj15/vol7PCuDrvpVlGWsWvx8JwCg/uA9piylwgkTV3/Hdw/Sb46VN/HIO24yccWf/PTOp0s4qrEsev1w52omXvKA04P8+/Yxpiw9U+pw/fsPmLjhU6GXAaj5qjNQ59yLbjNlv7X+wMQ9EnbKwe7Yj6Un5B14f5pzbTOnyPKCu6+QgSdp7cb7PP/E6iSfMiqYZ8+XN220q99yY8Ie11H59yy9vMtEfvJ5G1NWZ13ge2eBUPXPE/kfVEQ5bWS+9n0TPjTx5fGH/Ryddz/voZ9uNHEqluRxZMGxh0lERGSBDSYREZGFoKdk99zjrI5f5e38027p7zqp2Lo1JU0yvo7/vdr8uW/2HSZu9PeveRwZvrZcJ/Ok3GnY1/almjhju7OP4OMLZc5V1ehjJq4XI3MyZxxxvnR/685upkz9bL/TQnaaLDdYY8MmE1839ToAQPpA2dGmxkJJTabMDL00rJvOcoZt1HhS5uyd//wtJu5Z73cT14tzUrLNy8hAoNuX3mni+A8qmTjhE+++gvK7u+g+/3+m3t9N6lvFO9cslH358UUmfv6+3/M40o53cM5NCbuKfK6DOTK39uxv7wcApA4LrzRsrJJBTt59gjf0kMcTzpLrX+Ml+X/LusK5Nystfw+b2/qf233elc4OLpPqLnC9Vm6pU98+nb86AkDjaQMAAKn3Bu7ezh4mERGRBTaYREREFgKakn1pqWzg2uuSd/0e06y3s5TXb6dLV7/vTV+ZeGDFtSaOVU4q0DsCzeG/zfd221Mnyjy/Ro+FdpqvOHx66ZuunyR1MbhSusTXp+NUHx2SOazdJkoOptYLTtpF4a8i101nyGjPrI1Oerb+w5tyOzws5CyXjc+rdpXyBafLHNcFcc6SeDpeRllWXZmW53ndm3Q/UnWE6xFZFuy5Vdc451qf97kiSZ3PJK39yq2y/OBDlQt3DbJ10eaHP7P7TBP/1rW+iVM3BmbJz0Bz31u9c9hXXf2GKTt+lST95/eRHWAaxDr31mzXsoGNY+X+4/+1CjdP352G9X4tAQCpE5wRtfrUJxQj9jCJiIgssMEkIiKyENCUbK1xsuPCL62le35+nIzkNKNc+/kf7eruqHu74rl130ftayLnnemkg+s/LSPpAtlVDxW3vTfYxEv7yvJyd2yQpe+2HXUmuu/8vqYpqzteUlq1dofXyL5QlLVte/4H5SH2AXl+crT/3TWS3ih9CxZkr5bRw/Ovl3To+9fLxsYzB7wEAKgTU65Qr3FMy0T9oTsu8nn82/9v735CooijAI6/bTeVpNpDiOu22VKegkAkCOrexYztVIgR0cVLIfTn0KVIojSCjepQ3UKKKOzQQSpPEUV/2FtgSbhUkhBGZCa0Mh0Gf29gVvtZ7jq78/2cHvNb1mEW5vlmfu/3G9hu4tQDzwzl/Ng//b0gGfypyyzuqf/qG6+LaMrYteq7iVeIu1zmUi+BOjnrvsY5/UV/38cvt5p47jGsiIiT0516SoUKEwAACyWtMGPD2ltz7Ey3iZ+eu/xf3/upoJNH+ib0P4+PB1MmTr91X0KHoar0aj6v17zjfqcOjI6ZsGbmm4iIrJe8OVZNywNWsujmtIiI7E8+Kzp+d0qXF6wfcXsHq733cj7eajN5QeN948dFRGS6USegDB/pN/F4QW97Xdd6fN8b05Zkabjif9qSEE//4SLPOejO3tR7RvSwu9Tjw0ndxOH1Pa3qp7bofTi787aIiDREf5hjrbVabc44eqWeTLvLPq6M6LHfjv4mp+7oOcRH3Dv42oEX5liLaJ9lue/vVJgAAFggYQIAYKFsS+OtG9J+ytbUURPnurOL/q5M9oSJE5e8j0z8/YVh4+11dDw9gqgMo4caRUSkc3XxfS1v9Ow1ce2HV2U5p0oTv+W+jol7jnX17yj62SZhgpuXd7m7631zfaX6mHW+63VV3KU3I226/2d+t+5VHPNsOtJ0ceFr3izB7ZenwgQAwAIJEwAAC2V7JDs7oZvopno17ujdVuzjC0rwGAVVJNqiS6qdzAz6xjPv201c9yhn4rDNAEfwOW+0F3LD0u7dHAhUmAAAWCBhAgBgYdk3kAbC7tcm3fXhwJrPvvF3zzeaOF0oPnsWQOlRYQIAYIEKE1hmNUPaT9mebPONpwPclwaECRUmAAAWSJgAAFggYQIAYIGECQCABRImAAAWIo7DAlsAAPwNFSYAABZImAAAWCBhAgBggYQJAIAFEiYAABZImAAAWPgDQlqFmHMqmigAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 576x576 with 20 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(8, 8))\n",
    "for idx in range(20):\n",
    "    plt.subplot(4, 5, idx+1)\n",
    "    plt.axis('off')\n",
    "    # np.argmax()返回最大索引值\n",
    "    plt.title(\"[{}]\".format(np.argmax(mnist.train.labels[idx])))\n",
    "    plt.imshow(mnist.train.images[idx].reshape(28, 28))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "接下来，定义用于训练的网络，首先定义网络的输入。\n",
    "\n",
    "这里我们直接使用上面的数据作为输入，所以定义两个placeholder分别用于图像和lable数据，另外，定义一个bool类型的变量用于标识当前网络是否正在训练。\n",
    "\n",
    "为了让网络更高效的运行，多个数据会被组织成一个batch送入网络，两个placeholder的第一个维度就是batchsize，因为我们这里还没有确定batchsize，所以第一个维度留空。\n",
    "\n",
    "> **placeholder()函数是在神经网络构建graph的时候在模型中的占位，此时并没有把要输入的数据传入模型，它只会分配必要的内存。等建立session，在会话中，运行模型的时候通过feed_dict()函数向占位符喂入数据**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:32:51.706044Z",
     "start_time": "2018-06-01T06:32:51.698913Z"
    }
   },
   "outputs": [],
   "source": [
    "# 28*28 = 784，二维图像被拉抻成一维数组\n",
    "x = tf.placeholder(tf.float32, [None, 784], name='x')\n",
    "y = tf.placeholder(tf.float32, [None, 10], name='y')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "因为我们输入的是图片展开后的一维向量，所以第一步就需要先把一维向量还原为二维的图片。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:32:51.719298Z",
     "start_time": "2018-06-01T06:32:51.707730Z"
    }
   },
   "outputs": [],
   "source": [
    "'''\n",
    "[-1, 28, 28, 1]: \n",
    "-1: 表示未知具体个数，即不知道要有多少个图片，到时候通过自动计算进行赋值\n",
    "28, 28: 表示一张图片中x, y轴的像素数\n",
    "1: 表示满足28*28就是一张图片\n",
    "'''\n",
    "x_image = tf.reshape(x, [-1, 28, 28, 1])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:07:36.530623Z",
     "start_time": "2018-06-01T06:07:36.522665Z"
    }
   },
   "source": [
    "接下来，我们定义第一个卷积层，使用6个5X5的卷积核对输入数据进行卷积，padding方式选择valid，所以输出数据的宽高变为24x24,但是深度已经从原来的1变成了6，本层卷积的激活函数为relu。 \n",
    "\n",
    "**在tensorflow的整个结构中常常需要对变量或者对象进行共享，以来减少代码，其中对象就包括了各种卷积层，池化层，全连接网络层等等，所以接下来的代码中就使用<code>name_scope</code>来进行声明一个层的同时，也进行了占位（<code>[variable_scope](https://www.cnblogs.com/MY0213/p/9208503.html)</code>也是基于同样的思路），另外使用了<code>with</code>语句**\n",
    "> **1.在某个tf.name_scope()指定的区域中定义的所有对象及各种操作，他们的“name”属性上会增加该命名区的区域名，用以区别对象属于哪个区域；  \n",
    "2.将不同的对象及操作放在由tf.name_scope()指定的区域中，便于在tensorboard中展示清晰的逻辑关系图，这点在复杂关系图中特别重要**  \n",
    "\n",
    "> **With语句帮助上下文管理器对象实现了两个自动化的操作enter和exit，并充分考虑了异常情况。对于资源类对象（用完需要尽快释放）的使用，比如文件句柄、数据库连接等等，这无疑是一种简洁而完善的代码形式。**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:32:51.764292Z",
     "start_time": "2018-06-01T06:32:51.721295Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:Entity <bound method Conv.call of <tensorflow.python.layers.convolutional.Conv2D object at 0x0000011897057D08>> could not be transformed and will be executed as-is. Please report this to the AutgoGraph team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output. Cause: converting <bound method Conv.call of <tensorflow.python.layers.convolutional.Conv2D object at 0x0000011897057D08>>: AssertionError: Bad argument number for Name: 3, expecting 4\n",
      "WARNING: Entity <bound method Conv.call of <tensorflow.python.layers.convolutional.Conv2D object at 0x0000011897057D08>> could not be transformed and will be executed as-is. Please report this to the AutgoGraph team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output. Cause: converting <bound method Conv.call of <tensorflow.python.layers.convolutional.Conv2D object at 0x0000011897057D08>>: AssertionError: Bad argument number for Name: 3, expecting 4\n"
     ]
    }
   ],
   "source": [
    "with tf.name_scope(\"conv1\"):\n",
    "    C1 = slim.conv2d(\n",
    "        x_image,    # 输入数据\n",
    "        6,          # 6个卷积核\n",
    "        [5, 5],     # 卷积核大小\n",
    "        padding=\"VALID\",    # 选择补齐方式，VALID / SAME\n",
    "        activation_fn=tf.nn.relu    # 激活方式选择ReLU\n",
    "    )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "接下来进行stride为2的最大池化，池化后，输出深度不变，但是长宽减半，所以输出变成了12x12,深度6."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:32:51.774112Z",
     "start_time": "2018-06-01T06:32:51.766784Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:Entity <bound method Pooling2D.call of <tensorflow.python.layers.pooling.MaxPooling2D object at 0x0000011896EF1D08>> could not be transformed and will be executed as-is. Please report this to the AutgoGraph team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output. Cause: converting <bound method Pooling2D.call of <tensorflow.python.layers.pooling.MaxPooling2D object at 0x0000011896EF1D08>>: AssertionError: Bad argument number for Name: 3, expecting 4\n",
      "WARNING: Entity <bound method Pooling2D.call of <tensorflow.python.layers.pooling.MaxPooling2D object at 0x0000011896EF1D08>> could not be transformed and will be executed as-is. Please report this to the AutgoGraph team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output. Cause: converting <bound method Pooling2D.call of <tensorflow.python.layers.pooling.MaxPooling2D object at 0x0000011896EF1D08>>: AssertionError: Bad argument number for Name: 3, expecting 4\n"
     ]
    }
   ],
   "source": [
    "with tf.name_scope(\"pool1\"):\n",
    "    S2 = slim.max_pool2d(\n",
    "        C1,     # 输入数据\n",
    "        [2, 2], # 卷积核大小\n",
    "        stride=[2, 2],  # [2, 2]是怎么移动的？\n",
    "        padding=\"VALID\"\n",
    "    )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:10:16.678485Z",
     "start_time": "2018-06-01T06:10:16.671472Z"
    }
   },
   "source": [
    "接下来，我们定义第二个卷积层，使用16个5X5的卷积核对输入数据进行卷积，\n",
    "padding方式还是选择valid，输出8x8,深度为16，本层卷积的激活函数为relu。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:32:51.805912Z",
     "start_time": "2018-06-01T06:32:51.776959Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:Entity <bound method Conv.call of <tensorflow.python.layers.convolutional.Conv2D object at 0x000001189628E688>> could not be transformed and will be executed as-is. Please report this to the AutgoGraph team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output. Cause: converting <bound method Conv.call of <tensorflow.python.layers.convolutional.Conv2D object at 0x000001189628E688>>: AssertionError: Bad argument number for Name: 3, expecting 4\n",
      "WARNING: Entity <bound method Conv.call of <tensorflow.python.layers.convolutional.Conv2D object at 0x000001189628E688>> could not be transformed and will be executed as-is. Please report this to the AutgoGraph team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output. Cause: converting <bound method Conv.call of <tensorflow.python.layers.convolutional.Conv2D object at 0x000001189628E688>>: AssertionError: Bad argument number for Name: 3, expecting 4\n"
     ]
    }
   ],
   "source": [
    "with tf.name_scope(\"conv2\"):\n",
    "    C3 = slim.conv2d(\n",
    "        S2,    # 输入数据\n",
    "        16,         # 16个卷积核\n",
    "        [5, 5],     # 卷积核大小\n",
    "        padding=\"VALID\",    # 选择补齐方式，VALID / SAME\n",
    "        activation_fn=tf.nn.relu    # 激活方式选择ReLU\n",
    "    )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "再进行一次stride为2的最大池化，输出为4x4,深度16。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:32:51.814748Z",
     "start_time": "2018-06-01T06:32:51.807560Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:Entity <bound method Pooling2D.call of <tensorflow.python.layers.pooling.MaxPooling2D object at 0x0000011896F025C8>> could not be transformed and will be executed as-is. Please report this to the AutgoGraph team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output. Cause: converting <bound method Pooling2D.call of <tensorflow.python.layers.pooling.MaxPooling2D object at 0x0000011896F025C8>>: AssertionError: Bad argument number for Name: 3, expecting 4\n",
      "WARNING: Entity <bound method Pooling2D.call of <tensorflow.python.layers.pooling.MaxPooling2D object at 0x0000011896F025C8>> could not be transformed and will be executed as-is. Please report this to the AutgoGraph team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output. Cause: converting <bound method Pooling2D.call of <tensorflow.python.layers.pooling.MaxPooling2D object at 0x0000011896F025C8>>: AssertionError: Bad argument number for Name: 3, expecting 4\n"
     ]
    }
   ],
   "source": [
    "with tf.name_scope(\"pool2\"):\n",
    "    S4 = slim.max_pool2d(\n",
    "        C3,         # 输入数据\n",
    "        [2, 2],     # 卷积核大小\n",
    "        stride=[2, 2],  # 移动步长\n",
    "        padding=\"VALID\"\n",
    "    )   "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "池化后的数据是3维的，这里做一个拉平的操作，将3维数据展开到1维，然后送入两层全连接，全连接隐层中神经元个数分别为120，84。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:32:51.856740Z",
     "start_time": "2018-06-01T06:32:51.817287Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From D:\\Develop Kit\\anaconda3\\envs\\tf_gpu1.14\\lib\\site-packages\\tensorflow\\contrib\\layers\\python\\layers\\layers.py:1634: flatten (from tensorflow.python.layers.core) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Use keras.layers.flatten instead.\n",
      "WARNING:tensorflow:Entity <bound method Flatten.call of <tensorflow.python.layers.core.Flatten object at 0x0000011896EB2AC8>> could not be transformed and will be executed as-is. Please report this to the AutgoGraph team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output. Cause: converting <bound method Flatten.call of <tensorflow.python.layers.core.Flatten object at 0x0000011896EB2AC8>>: AttributeError: module 'gast' has no attribute 'Num'\n",
      "WARNING: Entity <bound method Flatten.call of <tensorflow.python.layers.core.Flatten object at 0x0000011896EB2AC8>> could not be transformed and will be executed as-is. Please report this to the AutgoGraph team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output. Cause: converting <bound method Flatten.call of <tensorflow.python.layers.core.Flatten object at 0x0000011896EB2AC8>>: AttributeError: module 'gast' has no attribute 'Num'\n",
      "WARNING:tensorflow:Entity <bound method Dense.call of <tensorflow.python.layers.core.Dense object at 0x0000011896F89888>> could not be transformed and will be executed as-is. Please report this to the AutgoGraph team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output. Cause: converting <bound method Dense.call of <tensorflow.python.layers.core.Dense object at 0x0000011896F89888>>: AssertionError: Bad argument number for Name: 3, expecting 4\n",
      "WARNING: Entity <bound method Dense.call of <tensorflow.python.layers.core.Dense object at 0x0000011896F89888>> could not be transformed and will be executed as-is. Please report this to the AutgoGraph team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output. Cause: converting <bound method Dense.call of <tensorflow.python.layers.core.Dense object at 0x0000011896F89888>>: AssertionError: Bad argument number for Name: 3, expecting 4\n",
      "WARNING:tensorflow:Entity <bound method Dense.call of <tensorflow.python.layers.core.Dense object at 0x0000011896F25D48>> could not be transformed and will be executed as-is. Please report this to the AutgoGraph team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output. Cause: converting <bound method Dense.call of <tensorflow.python.layers.core.Dense object at 0x0000011896F25D48>>: AssertionError: Bad argument number for Name: 3, expecting 4\n",
      "WARNING: Entity <bound method Dense.call of <tensorflow.python.layers.core.Dense object at 0x0000011896F25D48>> could not be transformed and will be executed as-is. Please report this to the AutgoGraph team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output. Cause: converting <bound method Dense.call of <tensorflow.python.layers.core.Dense object at 0x0000011896F25D48>>: AssertionError: Bad argument number for Name: 3, expecting 4\n"
     ]
    }
   ],
   "source": [
    "with tf.name_scope(\"fc1\"):\n",
    "    S4_flat = slim.flatten(S4)\n",
    "    C5 = slim.fully_connected(\n",
    "        S4_flat,\n",
    "        120,\n",
    "        activation_fn=tf.nn.relu\n",
    "    )\n",
    "\n",
    "with tf.name_scope(\"fc2\"):\n",
    "    C6 = slim.fully_connected(\n",
    "        C5,\n",
    "        84,\n",
    "        activation_fn=tf.nn.relu\n",
    "    )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:17:39.880958Z",
     "start_time": "2018-06-01T06:17:39.869797Z"
    }
   },
   "source": [
    "###### 对特征添加一个0.6的dropout，以40%的概率丢弃特征中的某些数据，\n",
    "这样可以提高网络的推广能力，减少过拟合的可能性。\n",
    "\n",
    "需要注意的是，dropout仅在训练的时候使用，验证的时候，需要关闭dropout，\n",
    "所以验证时候的keep_prob是1.0。\n",
    "\n",
    "dropout的输出最终送入一个隐层为10的全连接层，这个全连接层即为最后的分类器。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:32:51.913419Z",
     "start_time": "2018-06-01T06:32:51.860766Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From <ipython-input-11-080d416b37e8>:6: calling dropout (from tensorflow.python.ops.nn_ops) with keep_prob is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please use `rate` instead of `keep_prob`. Rate should be set to `rate = 1 - keep_prob`.\n"
     ]
    }
   ],
   "source": [
    "# 定义一个名为\"keep_prod\"的graph占位，用于dropout\n",
    "with tf.name_scope(\"dropout\"):\n",
    "    keep_prob = tf.placeholder(tf.float32, name=\"keep_prob\")\n",
    "    C6_drop = tf.nn.dropout(\n",
    "        C6,\n",
    "        keep_prob\n",
    "    )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:Entity <bound method Dense.call of <tensorflow.python.layers.core.Dense object at 0x0000011897010188>> could not be transformed and will be executed as-is. Please report this to the AutgoGraph team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output. Cause: converting <bound method Dense.call of <tensorflow.python.layers.core.Dense object at 0x0000011897010188>>: AssertionError: Bad argument number for Name: 3, expecting 4\n",
      "WARNING: Entity <bound method Dense.call of <tensorflow.python.layers.core.Dense object at 0x0000011897010188>> could not be transformed and will be executed as-is. Please report this to the AutgoGraph team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output. Cause: converting <bound method Dense.call of <tensorflow.python.layers.core.Dense object at 0x0000011897010188>>: AssertionError: Bad argument number for Name: 3, expecting 4\n"
     ]
    }
   ],
   "source": [
    "'''\n",
    "问题：声明在C5和C6的slim.fully_connected()里120，84为神经元数目，为何在logits中10却为隐层数目？\n",
    "'''\n",
    "with tf.name_scope(\"fc3\"):\n",
    "    logits = tf.contrib.slim.fully_connected(\n",
    "        C6_drop,\n",
    "        10, # 经过十个全连接层的处理后，会输出对0到9十个数字的分类\n",
    "        activation_fn=None  # 最后一层不需要激活函数，之后会用softmax处理，得出每种可能的概率\n",
    "    )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "接下来定义loss和用于优化网络的优化器。loss计算使用了softmax_cross_entropy_with_logits，这样做的好处是labels可以不用手动做one_hot省了一些麻烦。这里使用了sgd优化器，学习率为0.3。\n",
    "> tf.nn.softmax_cross_entropy_with_logits（）函数已经过时 (deprecated)，它在TensorFlow未来的版本中将被去除。取而代之的是tf.nn.softmax_cross_entropy_with_logits_v2（）\n",
    "\n",
    "- 定义交叉熵损失：对上一层输出未经激活的logits结果进行softmax激活，然后再计算交叉熵损失，先激活在计算，两步合为一步,最后进行reduce_mean，就得到交叉熵损失\n",
    ">试试看，增大减小学习率，换个优化器再进行训练会发生什么。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:32:52.084738Z",
     "start_time": "2018-06-01T06:32:51.915376Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From <ipython-input-13-b174ac857ad0>:2: softmax_cross_entropy_with_logits (from tensorflow.python.ops.nn_ops) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "\n",
      "Future major versions of TensorFlow will allow gradients to flow\n",
      "into the labels input on backprop by default.\n",
      "\n",
      "See `tf.nn.softmax_cross_entropy_with_logits_v2`.\n",
      "\n"
     ]
    }
   ],
   "source": [
    "cross_entripy_loss = tf.reduce_mean(\n",
    "    tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=y)\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "从模型中取出训练权重，然后进行L2正则化操作，最后求和\n",
    "> <code>tf.add_n([list])</code>: 求list中元素的累加和，列表里的元素可以是向量，矩阵等"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "'''\n",
    "问题：语法没看懂，tf.nn.l2_loss(w)回车后接一个for循环？\n",
    "解答：python高阶语法，列表推导式\n",
    "'''\n",
    "l2_loss = tf.add_n(\n",
    "    [\n",
    "        tf.nn.l2_loss(w) for w in tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES)\n",
    "        # tf.get_collection('losses'):获取集合“losses”中的所有元素，生成一个列表并返回该列表\n",
    "    ]\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> <code>tf.summary.histogram()</code>将输入的一个任意大小和形状的张量压缩成一个由宽度和数量组成的直方图数据结构．假设输入$[0.5, 1.1, 1.3, 2.2, 2.9, 2.99]$，则可以创建三个bin，分别包含$0-1$之间/$1-2$之间/$2-3$之间的所有元素，即三个bin中的元素分别为$[0.5]／[1.1, 1.3]/[2.2, 2.9, 2.99]$．这样，通过可视化张量在不同时间点的直方图来显示某些分布随时间变化的情况．"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Conv/weights:0\n",
      "INFO:tensorflow:Summary name Conv/weights:0 is illegal; using Conv/weights_0 instead.\n",
      "Conv/biases:0\n",
      "INFO:tensorflow:Summary name Conv/biases:0 is illegal; using Conv/biases_0 instead.\n",
      "Conv_1/weights:0\n",
      "INFO:tensorflow:Summary name Conv_1/weights:0 is illegal; using Conv_1/weights_0 instead.\n",
      "Conv_1/biases:0\n",
      "INFO:tensorflow:Summary name Conv_1/biases:0 is illegal; using Conv_1/biases_0 instead.\n",
      "fully_connected/weights:0\n",
      "INFO:tensorflow:Summary name fully_connected/weights:0 is illegal; using fully_connected/weights_0 instead.\n",
      "fully_connected/biases:0\n",
      "INFO:tensorflow:Summary name fully_connected/biases:0 is illegal; using fully_connected/biases_0 instead.\n",
      "fully_connected_1/weights:0\n",
      "INFO:tensorflow:Summary name fully_connected_1/weights:0 is illegal; using fully_connected_1/weights_0 instead.\n",
      "fully_connected_1/biases:0\n",
      "INFO:tensorflow:Summary name fully_connected_1/biases:0 is illegal; using fully_connected_1/biases_0 instead.\n",
      "fully_connected_2/weights:0\n",
      "INFO:tensorflow:Summary name fully_connected_2/weights:0 is illegal; using fully_connected_2/weights_0 instead.\n",
      "fully_connected_2/biases:0\n",
      "INFO:tensorflow:Summary name fully_connected_2/biases:0 is illegal; using fully_connected_2/biases_0 instead.\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<tf.Tensor 'total_loss:0' shape=() dtype=string>"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 这一部分是为了tensorboard做准备\n",
    "for w in tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES):\n",
    "    print(w.name)\n",
    "    tf.summary.histogram(w.name, w)\n",
    "\n",
    "# 交叉熵损失和加权l2损失的相加之和\n",
    "total_loss = cross_entripy_loss + 7e-5 * l2_loss\n",
    "\n",
    "tf.summary.scalar('cross_entropy_loss', cross_entripy_loss)\n",
    "tf.summary.scalar('l2_loss', l2_loss)\n",
    "tf.summary.scalar('total_loss', total_loss)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Tensor(\"add:0\", shape=(), dtype=float32)\n"
     ]
    }
   ],
   "source": [
    "print(total_loss)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 梯度下降优化器\n",
    "optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.3).minimize(total_loss)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:25:56.449132Z",
     "start_time": "2018-06-01T06:25:56.438340Z"
    }
   },
   "source": [
    "需要注意的是，上面的网络，最后输出的是未经softmax的原始logits，而不是概率分布，\n",
    "要想看到概率分布，还需要做一下softmax。\n",
    "\n",
    "将输出的结果与正确结果进行对比，即可得到我们的网络输出结果的准确率。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:39:50.010829Z",
     "start_time": "2018-06-01T06:39:49.997501Z"
    }
   },
   "outputs": [],
   "source": [
    "pred = tf.nn.softmax(logits)\n",
    "correct_pred = tf.equal(tf.argmax(y, 1), tf.argmax(logits, 1))\n",
    "accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "saver用于保存或恢复训练的模型。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:32:52.127795Z",
     "start_time": "2018-06-01T06:32:52.103115Z"
    }
   },
   "outputs": [],
   "source": [
    "# 55000*2=100*1100，将训练数据全部训练两遍，epoch=2\n",
    "batch_size = 100\n",
    "trainig_step = 1100\n",
    "\n",
    "saver = tf.train.Saver()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "以上定义的所有操作，均为计算图，也就是仅仅是定义了网络的结构，实际需要运行的话，还需要创建一个session，并将数据填入网络中。\n",
    "> **merge_all 可以将所有summary全部保存到磁盘，以便tensorboard显示。如果没有特殊要求，一般用这一句就可一显示训练时的各种信息了**\n",
    "\n",
    "> **tf.Session.run()函数返回值为fetches的执行结果。如果fetches是一个元素就返回一个值；若fetches是一个list，则返回list的值，若fetches是一个字典类型，则返回和fetches同keys的字典**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:35:22.270272Z",
     "start_time": "2018-06-01T06:33:18.829198Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "after 100 training steps, the loss is 0.382662, the validation accuracy is 0.8988\n",
      "after 200 training steps, the loss is 0.31935, the validation accuracy is 0.9484\n",
      "after 300 training steps, the loss is 0.242528, the validation accuracy is 0.9606\n",
      "after 400 training steps, the loss is 0.249773, the validation accuracy is 0.9646\n",
      "after 500 training steps, the loss is 0.120766, the validation accuracy is 0.969\n",
      "after 600 training steps, the loss is 0.159676, the validation accuracy is 0.9732\n",
      "WARNING:tensorflow:From D:\\Develop Kit\\anaconda3\\envs\\tf_gpu1.14\\lib\\site-packages\\tensorflow\\python\\training\\saver.py:960: remove_checkpoint (from tensorflow.python.training.checkpoint_management) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Use standard file APIs to delete files with this prefix.\n",
      "after 700 training steps, the loss is 0.0496258, the validation accuracy is 0.9744\n",
      "after 800 training steps, the loss is 0.0870623, the validation accuracy is 0.9758\n",
      "after 900 training steps, the loss is 0.0869705, the validation accuracy is 0.9812\n",
      "after 1000 training steps, the loss is 0.0673272, the validation accuracy is 0.97\n",
      "the training is finish!\n",
      "the test accuracy is : 0.9804\n"
     ]
    }
   ],
   "source": [
    "#每次运行merged，会从整个网络收集summary\n",
    "merged = tf.summary.merge_all()\n",
    "\n",
    "with tf.Session() as sess:\n",
    "    writer = tf.summary.FileWriter(\"./zuoye/logs/\",sess.graph)\n",
    "    # 初始化\n",
    "    sess.run(tf.global_variables_initializer())\n",
    "    \n",
    "    # 定义验证集和测试集\n",
    "    validation_data = {\n",
    "        # placeholder\n",
    "        x: mnist.validation.images,\n",
    "        y: mnist.validation.labels,\n",
    "        keep_prob:1.0\n",
    "    }\n",
    "    test_data = {\n",
    "        x: mnist.test.images,\n",
    "        y: mnist.test.labels,\n",
    "        keep_prob:1.0\n",
    "    }\n",
    "    # 训练过程\n",
    "    for i in range(trainig_step):\n",
    "        xs, ys = mnist.train.next_batch(batch_size)\n",
    "        _, loss, rs = sess.run(\n",
    "            [optimizer, cross_entripy_loss, merged],\n",
    "            feed_dict={\n",
    "                x:xs,\n",
    "                y:ys,\n",
    "                keep_prob:0.6\n",
    "            }\n",
    "        )\n",
    "        # 写到磁盘，为了分析\n",
    "        writer.add_summary(rs, i)\n",
    "        \n",
    "        # 每100次训练打印一次损失值与验证准确率\n",
    "        if i>0 and i % 100 == 0:\n",
    "            validate_accuracy = sess.run(accuracy, feed_dict=validation_data)\n",
    "            print(\n",
    "                \"after %d training steps, the loss is %g, the validation accuracy is %g\" % (i, loss, validate_accuracy)\n",
    "            )\n",
    "            saver.save(sess, \"./zuoye/model.ckpt\",global_step=i)\n",
    "            \n",
    "    print(\"the training is finish!\")\n",
    "    # 最终的测试准确率\n",
    "    acc = sess.run(accuracy, feed_dict=test_data)\n",
    "    print(\"the test accuracy is :\", acc)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:58:16.766415Z",
     "start_time": "2018-06-01T06:58:15.918700Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From D:\\Develop Kit\\anaconda3\\envs\\tf_gpu1.14\\lib\\site-packages\\tensorflow\\python\\training\\saver.py:1276: checkpoint_exists (from tensorflow.python.training.checkpoint_management) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Use standard file APIs to check for files with this prefix.\n",
      "INFO:tensorflow:Restoring parameters from ./zuoye/model.ckpt-1000\n",
      "1.0\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 576x576 with 16 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "with tf.Session() as sess:\n",
    "    ckpt = tf.train.get_checkpoint_state('./zuoye/')\n",
    "    if ckpt and ckpt.model_checkpoint_path:\n",
    "        saver.restore(sess, ckpt.model_checkpoint_path)\n",
    "        final_pred, acc =sess.run(\n",
    "        [pred, accuracy],\n",
    "        feed_dict={\n",
    "            x: mnist.test.images[:16],  # 前16行数据导入给x\n",
    "            y: mnist.test.labels[:16],\n",
    "            keep_prob:1.0\n",
    "        }) \n",
    "    orders = np.argsort(final_pred)  # 返回的是final_pred的大小排列的索引值的列表,这里的final_pred是softmax后的概率分布\n",
    "    plt.figure(figsize = (8, 8))\n",
    "    print(acc)\n",
    "    for idx in range(16):\n",
    "        order = orders[idx, :][-1] # 表示取第idx行数据的最后一个值，也就是概率最大的值的索引值\n",
    "        prob = final_pred[idx, :][order]  # 对应的就是取到了这行数据中概率最大的概率值\n",
    "        plt.subplot(4, 4, idx+1)\n",
    "        plt.axis(\"off\")\n",
    "        plt.title('{}: [{}]-[{:.1f}%]'.format(np.argmax(mnist.test.labels[idx]),order, prob*100))\n",
    "        plt.imshow(mnist.test.images[idx].reshape(28,28))\n",
    "        \n",
    "    else:\n",
    "        pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.7"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": true
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
